<?php
/**
 * Short description
 *
 * Long description
 *
 *
 * Copyright 2008, Renan Gonçalves <renan.saddam@gmail.com>
 * Licensed under The MIT License
 * Redistributions of files must retain the copyright notice.
 *
 * @copyright       Copyright 2008, Renan Gonçalves
 * @category        Cushy
 * @package         Cushy_Correios
 * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
 */
class Cushy_Correios_Model_Carrier_Correios extends Mage_Shipping_Model_Carrier_Abstract
	implements Mage_Shipping_Model_Carrier_Interface {

	/**
	 * _code property
	 *
	 * @var string
	 */
	protected $_code = 'correios';

	/**
	 * _result property
	 *
	 * @var Mage_Shipping_Model_Rate_Result / Mage_Shipping_Model_Tracking_Result
	 */
	protected $_result = null;

	/**
	 * Check if current carrier offer support to tracking
	 *
	 * @return boolean true
	 */
	public function isTrackingAvailable() {
		return true;
	}

	/**
	 * Collect Rates
	 *
	 * @param Mage_Shipping_Model_Rate_Request $request
	 * @return Mage_Shipping_Model_Rate_Result
	 */
	public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
		if (!$this->getConfigFlag('active')) {
			return false;
		}
		$result = Mage::getModel('shipping/rate_result');

		$error = Mage::getModel('shipping/rate_result_error');
		$error->setCarrier($this->_code);
		$error->setCarrierTitle($this->getConfigData('title'));

		$postcode = array(
			'origin' => trim(Mage::getStoreConfig('shipping/origin/postcode', $this->getStore())),
			'dest' => trim($request->getDestPostcode())
		);

		$weight = $request->getPackageWeight();
		if ($weight > $this->getConfigData('max_package_weight')){
			$error->setErrorMessage('Weight exceeded limit');
			$result->append($error);
			return $result;
		}

		$methods = array(
			array('name' => 'PAC', 'code' => 41106, 'deadline' => 'de 3 a 15 dias úteis'),
			array('name' => 'Sedex', 'code' => 40010, 'deadline' => 'de 2 a 5 dias úteis'),
			array('name' => 'Sedex 10', 'code' => 40215, 'deadline' => 'até as dez horas do dia seguinte'),
			array('name' => 'Sedex HOJE', 'code' => 40290, 'deadline' => 'de 1 a 3 dias úteis'),
			array('name' => 'E-Sedex', 'code' => 81019,	'deadline' => 'de 3 a 15 dias úteis')
		);
		foreach($methods as $method) {
			$client = new Zend_Http_Client('http://www.correios.com.br/encomendas/precos/calculo.cfm');
			$client->setParameterGet('resposta', 'xml');
			$client->setParameterGet('servico', $method['code']);
			$client->setParameterGet('peso', $weight);
			$client->setParameterGet('cepOrigem', $postcode['origin']);
			$client->setParameterGet('cepDestino', $postcode['dest']);

			try {
				$content = $client->request();
				$xml = simplexml_load_string($content->getBody());
			} catch (Exception $e) {
				continue;
			}

			$shippingPrice = floatval($xml->dados_postais->preco_postal);
			if ($shippingPrice <= 0) {
				continue;
			}

			$_method = Mage::getModel('shipping/rate_result_method');
			$_method->setCarrier($this->_code);
			$_method->setCarrierTitle($this->getConfigData('name'));
			$_method->setMethod($method['name']);
			$_method->setMethodTitle($method['name'] . ' - ' . $method['deadline']);
			$_method->setPrice($shippingPrice + $this->getConfigData('handling_fee'));
			$_method->setCost($shippingPrice);

			$result->append($_method);
		}

		$this->_result = $result;
		$this->_updateFreeMethodQuote($request);
		return $this->_result;
	}

	/**
	 * Get Tracking Info
	 *
	 * @param mixed $tracking
	 * @return mixed
	 */
	public function getTrackingInfo($tracking) {
		$result = $this->getTracking($tracking);
		if ($result instanceof Mage_Shipping_Model_Tracking_Result){
			if ($trackings = $result->getAllTrackings()) {
				return $trackings[0];
			}
		} elseif (is_string($result) && !empty($result)) {
			return $result;
		}

		return false;
	}

	/**
	 * Get Tracking
	 *
	 * @param array $trackings
	 * @return Mage_Shipping_Model_Tracking_Result
	 */
	public function getTracking($trackings) {
		$this->_result = Mage::getModel('shipping/tracking_result');
		foreach ((array) $trackings as $code) {
			$this->_getTracking($code);
		}

		return $this->_result;
	}

	/**
	 * Protected Get Tracking, opens the request to Correios
	 *
	 * @param string $code
	 * @return boolean
	 */
	protected function _getTracking($code) {
		$error = Mage::getModel('shipping/tracking_result_error');
		$error->setTracking($code);
		$error->setCarrier('correios');
		$error->setCarrierTitle($this->getConfigData('title'));
		$error->setErrorMessage($this->getConfigData('specificerrmsg'));

		$url = 'http://websro.correios.com.br/sro_bin/txect01$.QueryList';
		$url .= '?P_LINGUA=001&P_TIPO=001&P_COD_UNI=' . $code;
		try {
			$client = new Zend_Http_Client();
			$client->setUri($url);
			$content = $client->request();
		} catch (Exception $e) {
			$this->_result->append($error);
			return false;
		}

		if (!eregi('<table[^>]+>(.*)</table>', $content->getBody(), $matches)) {
			$this->_result->append($error);
			return false;
		}
		$table = $matches[1];

		if (!preg_match_all('/<tr>(.*)<\/tr>/', $table, $columns, PREG_SET_ORDER)) {
			$this->_result->append($error);
			return false;
		}

		$progress = array();
		for ($i = 0; $i < count($columns); $i++) {
			$column = $columns[$i][1];

			$description = '';
			$found = false;
			if (eregi('^<td rowspan="?2"?', $column) && eregi('<td rowspan="?2"?>(.*)</td><td>(.*)</td><td><font color="[A-Z0-9]{6}">(.*)</font></td>', $column, $matches)) {
				if (eregi('<td colspan="?2"?>(.*)</td>', $columns[$i+1][1], $matchesDescription)) {
					$description = str_replace('  ', '', $matchesDescription[1]);
				}

				$found = true;
			} elseif (eregi('<td rowspan="?1"?>(.*)</td><td>(.*)</td><td><font color="[A-Z0-9]{6}">(.*)</font></td>', $column, $matches)) {
				$found = true;
			}

			if ($found) {
				$datetime = split(' ', $matches[1]);
				$track = array(
					'deliverydate' => $datetime[0],
					'deliverytime' => $datetime[1] . ':00',
					'deliverylocation' => $matches[2],
					'status' => $matches[3],
					'activity' => $matches[3]
				);
				if ($description !== '') {
					$track['activity'] = $matches[3] . ' - ' . utf8_encode($description);
				}

				$progress[] = $track;
			}
		}

		if (!empty($progress)) {
			$track = $progress[0];
			$track['progressdetail'] = $progress;

			$tracking = Mage::getModel('shipping/tracking_result_status');
			$tracking->setTracking($code);
			$tracking->setCarrier('correios');
			$tracking->setCarrierTitle($this->getConfigData('title'));
			$tracking->addData($track);

			$this->_result->append($tracking);
			return true;
		} else {
			$this->_result->append($error);
			return false;
		}
	}

	/**
	 * Returns the allowed carrier methods
	 *
	 * @return array
	 */
	public function getAllowedMethods() {
		return array($this->_code => $this->getConfigData('title'));
	}
}
